package com.bbs.common;

import com.bbs.util.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

/**
 * 全局异常处理
 */

@RestControllerAdvice  // 为所有控制器提供一个全局的异常处理程序和响应结果处理程序
public class MyBBSExceptionHandler {

    /**
     * 处理全局异常的控制器方法。
     * 当发生异常时，此方法会捕获异常，并根据请求的类型返回不同的响应。
     *
     * @param e 发生的异常对象
     * @param req HttpServletRequest对象，用于获取请求信息
     * @return 根据请求是否为AJAX请求，返回不同的结果。如果是AJAX请求，则返回一个包含错误信息的Result对象；
     *         如果不是，则返回一个指向错误页面的ModelAndView对象。
     */
    @ExceptionHandler(Exception.class)
    public Object handleException(Exception e, HttpServletRequest req) {
        Result result = new Result();
        result.setResultCode(500); // 设置默认的错误代码为500

        e.printStackTrace(); // 打印堆栈信息，用于调试
        result.setMessage("未知异常，请联系管理员"); // 设置默认的错误信息

        // 检查请求是否为ajax, 根据请求头判断
        String contentTypeHeader = req.getHeader("Content-Type");
        String acceptHeader = req.getHeader("Accept");
        String xRequestedWith = req.getHeader("X-Requested-With");
        if ((contentTypeHeader != null && contentTypeHeader.contains("application/json"))
                || (acceptHeader != null && acceptHeader.contains("application/json"))
                || "XMLHttpRequest".equalsIgnoreCase(xRequestedWith)) {
            // 如果是AJAX请求，则返回JSON格式的错误信息
            return result;
        } else {
            // 如果不是AJAX请求，则返回一个错误页面
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("message", e.getMessage()); // 添加异常信息
            modelAndView.addObject("url", req.getRequestURL()); // 添加请求URL
            modelAndView.addObject("stackTrace", e.getStackTrace()); // 添加堆栈跟踪信息
            modelAndView.addObject("author", "rambo"); // 添加错误页面的作者信息
            modelAndView.addObject("ltd", "My BBS"); // 添加公司信息
            modelAndView.setViewName("error"); // 设置错误页面的视图名称
            return modelAndView;
        }
    }
}
